package org.misalen.web.support.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;

import org.apache.commons.beanutils.BeanUtils;

public class ResultSetMapper<T> {
	@SuppressWarnings("unchecked")
	public List<T> mapRersultSetToObject(ResultSet rs, Class<?> outputClass) {
		List<T> outputList = new ArrayList<T>();
		try {
			if (rs != null) {
				if (outputClass.isAnnotationPresent(Entity.class)) {
					ResultSetMetaData rsmd = rs.getMetaData();
					Field[] fields = outputClass.getDeclaredFields();
					while (rs.next()) {
						T bean = (T) outputClass.newInstance();
						for (int _iterator = 0; _iterator < rsmd.getColumnCount(); _iterator++) {
							String columnName = rsmd.getColumnName(_iterator + 1);
							Object columnValue = rs.getObject(_iterator + 1);
							if (columnName.equals("id")) {
								BeanUtils.setProperty(bean, "id", columnValue);
							} else {
								for (Field field : fields) {
									if (field.isAnnotationPresent(Column.class)) {
										Column column = field.getAnnotation(Column.class);
										if (column.name().equalsIgnoreCase(columnName) && columnValue != null) {
											BeanUtils.setProperty(bean, field.getName(), columnValue);
											break;
										}
									}
								}
							}

						}
						outputList.add(bean);
					}

				}
			}
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return outputList;
	}

	/**
	 * 将resultSet转化为实体类（实体字段全为String类型）
	 * 
	 * @param rs
	 * @param dto
	 * @return
	 * @throws Exception
	 */
	public static <T> T bindDataToDTO(ResultSet rs, T dto) throws Exception {

		// 取得Method方法
		Method[] methods = dto.getClass().getMethods();

		// 取得ResultSet的列名
		ResultSetMetaData rsmd = rs.getMetaData();
		int columnsCount = rsmd.getColumnCount();
		String[] columnNames = new String[columnsCount];
		for (int i = 0; i < columnsCount; i++) {
			columnNames[i] = rsmd.getColumnLabel(i + 1);
		}

		// 遍历ResultSet
		while (rs.next()) {
			// 反射, 从ResultSet绑定到JavaBean
			for (int i = 0; i < columnNames.length; i++) {
				// 取得Set方法
				String setMethodName = "set" + columnNames[i];
				// 遍历Method
				for (int j = 0; j < methods.length; j++) {
					if (methods[j].getName().equalsIgnoreCase(setMethodName)) {
						setMethodName = methods[j].getName();
						Object value = rs.getObject(columnNames[i]);

						// 实行Set方法
						try {
							// JavaBean内部属性和ResultSet中一致时候
							if (value != null) {
								Method setMethod = dto.getClass().getMethod(setMethodName, value.getClass());
								setMethod.invoke(dto, value);
							}
						} catch (Exception e) {
							// JavaBean内部属性和ResultSet中不一致时候，使用String来输入值。
							Method setMethod = dto.getClass().getMethod(setMethodName, String.class);
							setMethod.invoke(dto, value.toString());
						}
					}
				}
			}
		}
		return dto;
	}
}